home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / bsp / qbsp3 / writebsp.c < prev   
Encoding:
C/C++ Source or Header  |  1997-11-26  |  10.6 KB  |  570 lines

  1. #include "qbsp.h"
  2.  
  3. int        c_nofaces;
  4. int        c_facenodes;
  5.  
  6.  
  7. /*
  8. =========================================================
  9.  
  10. ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES
  11.  
  12. =========================================================
  13. */
  14.  
  15. int        planeused[MAX_MAP_PLANES];
  16.  
  17. /*
  18. ============
  19. EmitPlanes
  20.  
  21. There is no oportunity to discard planes, because all of the original
  22. brushes will be saved in the map.
  23. ============
  24. */
  25. void EmitPlanes (void)
  26. {
  27.     int            i;
  28.     dplane_t    *dp;
  29.     plane_t        *mp;
  30.     int        planetranslate[MAX_MAP_PLANES];
  31.  
  32.     mp = mapplanes;
  33.     for (i=0 ; i<nummapplanes ; i++, mp++)
  34.     {
  35.         dp = &dplanes[numplanes];
  36.         planetranslate[i] = numplanes;
  37.         VectorCopy ( mp->normal, dp->normal);
  38.         dp->dist = mp->dist;
  39.         dp->type = mp->type;
  40.         numplanes++;
  41.     }
  42. }
  43.  
  44.  
  45. //========================================================
  46.  
  47. void EmitMarkFace (dleaf_t *leaf_p, face_t *f)
  48. {
  49.     int            i;
  50.     int            facenum;
  51.  
  52.     while (f->merged)
  53.         f = f->merged;
  54.  
  55.     if (f->split[0])
  56.     {
  57.         EmitMarkFace (leaf_p, f->split[0]);
  58.         EmitMarkFace (leaf_p, f->split[1]);
  59.         return;
  60.     }
  61.  
  62.     facenum = f->outputnumber;
  63.     if (facenum == -1)
  64.         return;    // degenerate face
  65.  
  66.     if (facenum < 0 || facenum >= numfaces)
  67.         Error ("Bad leafface");
  68.     for (i=leaf_p->firstleafface ; i<numleaffaces ; i++)
  69.         if (dleaffaces[i] == facenum)
  70.             break;        // merged out face
  71.     if (i == numleaffaces)
  72.     {
  73.         if (numleaffaces >= MAX_MAP_LEAFFACES)
  74.             Error ("MAX_MAP_LEAFFACES");
  75.  
  76.         dleaffaces[numleaffaces] =  facenum;
  77.         numleaffaces++;
  78.     }
  79.  
  80. }
  81.  
  82.  
  83. /*
  84. ==================
  85. EmitLeaf
  86. ==================
  87. */
  88. void EmitLeaf (node_t *node)
  89. {
  90.     dleaf_t        *leaf_p;
  91.     portal_t    *p;
  92.     int            s;
  93.     face_t        *f;
  94.     bspbrush_t    *b;
  95.     int            i;
  96.     int            brushnum;
  97.  
  98.     // emit a leaf
  99.     if (numleafs >= MAX_MAP_LEAFS)
  100.         Error ("MAX_MAP_LEAFS");
  101.  
  102.     leaf_p = &dleafs[numleafs];
  103.     numleafs++;
  104.  
  105.     leaf_p->contents = node->contents;
  106.     leaf_p->cluster = node->cluster;
  107.     leaf_p->area = node->area;
  108.  
  109.     //
  110.     // write bounding box info
  111.     //    
  112.     VectorCopy (node->mins, leaf_p->mins);
  113.     VectorCopy (node->maxs, leaf_p->maxs);
  114.     
  115.     //
  116.     // write the leafbrushes
  117.     //
  118.     leaf_p->firstleafbrush = numleafbrushes;
  119.     for (b=node->brushlist ; b ; b=b->next)
  120.     {
  121.         if (numleafbrushes >= MAX_MAP_LEAFBRUSHES)
  122.             Error ("MAX_MAP_LEAFBRUSHES");
  123.  
  124.         brushnum = b->original - mapbrushes;
  125.         for (i=leaf_p->firstleafbrush ; i<numleafbrushes ; i++)
  126.             if (dleafbrushes[i] == brushnum)
  127.                 break;
  128.         if (i == numleafbrushes)
  129.         {
  130.             dleafbrushes[numleafbrushes] = brushnum;
  131.             numleafbrushes++;
  132.         }
  133.     }
  134.     leaf_p->numleafbrushes = numleafbrushes - leaf_p->firstleafbrush;
  135.  
  136.     //
  137.     // write the leaffaces
  138.     //
  139.     if (leaf_p->contents & CONTENTS_SOLID)
  140.         return;        // no leaffaces in solids
  141.  
  142.     leaf_p->firstleafface = numleaffaces;
  143.  
  144.     for (p = node->portals ; p ; p = p->next[s])    
  145.     {
  146.         s = (p->nodes[1] == node);
  147.         f = p->face[s];
  148.         if (!f)
  149.             continue;    // not a visible portal
  150.  
  151.         EmitMarkFace (leaf_p, f);
  152.     }
  153.     
  154.     leaf_p->numleaffaces = numleaffaces - leaf_p->firstleafface;
  155. }
  156.  
  157.  
  158. /*
  159. ==================
  160. EmitFace
  161. ==================
  162. */
  163. void EmitFace (face_t *f)
  164. {
  165.     dface_t    *df;
  166.     int        i;
  167.     int        e;
  168.  
  169.     f->outputnumber = -1;
  170.  
  171.     if (f->numpoints < 3)
  172.     {
  173.         return;        // degenerated
  174.     }
  175.     if (f->merged || f->split[0] || f->split[1])
  176.     {
  177.         return;        // not a final face
  178.     }
  179.  
  180.     // save output number so leaffaces can use
  181.     f->outputnumber = numfaces;
  182.  
  183.     if (numfaces >= MAX_MAP_FACES)
  184.         Error ("numfaces == MAX_MAP_FACES");
  185.     df = &dfaces[numfaces];
  186.     numfaces++;
  187.  
  188.     // planenum is used by qlight, but not quake
  189.     df->planenum = f->planenum & (~1);
  190.     df->side = f->planenum & 1;
  191.  
  192.     df->firstedge = numsurfedges;
  193.     df->numedges = f->numpoints;
  194.     df->texinfo = f->texinfo;
  195.     for (i=0 ; i<f->numpoints ; i++)
  196.     {
  197. //        e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f);
  198.         e = GetEdge2 (f->vertexnums[i], f->vertexnums[(i+1)%f->numpoints], f);
  199.         if (numsurfedges >= MAX_MAP_SURFEDGES)
  200.             Error ("numsurfedges == MAX_MAP_SURFEDGES");
  201.         dsurfedges[numsurfedges] = e;
  202.         numsurfedges++;
  203.     }
  204. }
  205.  
  206. /*
  207. ============
  208. EmitDrawingNode_r
  209. ============
  210. */
  211. int EmitDrawNode_r (node_t *node)
  212. {
  213.     dnode_t    *n;
  214.     face_t    *f;
  215.     int        i;
  216.  
  217.     if (node->planenum == PLANENUM_LEAF)
  218.     {
  219.         EmitLeaf (node);
  220.         return -numleafs;
  221.     }
  222.  
  223.     // emit a node    
  224.     if (numnodes == MAX_MAP_NODES)
  225.         Error ("MAX_MAP_NODES");
  226.     n = &dnodes[numnodes];
  227.     numnodes++;
  228.  
  229.     VectorCopy (node->mins, n->mins);
  230.     VectorCopy (node->maxs, n->maxs);
  231.  
  232.     planeused[node->planenum]++;
  233.     planeused[node->planenum^1]++;
  234.  
  235.     if (node->planenum & 1)
  236.         Error ("WriteDrawNodes_r: odd planenum");
  237.     n->planenum = node->planenum;
  238.     n->firstface = numfaces;
  239.  
  240.     if (!node->faces)
  241.         c_nofaces++;
  242.     else
  243.         c_facenodes++;
  244.  
  245.     for (f=node->faces ; f ; f=f->next)
  246.         EmitFace (f);
  247.  
  248.     n->numfaces = numfaces - n->firstface;
  249.  
  250.  
  251.     //
  252.     // recursively output the other nodes
  253.     //    
  254.     for (i=0 ; i<2 ; i++)
  255.     {
  256.         if (node->children[i]->planenum == PLANENUM_LEAF)
  257.         {
  258.             n->children[i] = -(numleafs + 1);
  259.             EmitLeaf (node->children[i]);
  260.         }
  261.         else
  262.         {
  263.             n->children[i] = numnodes;    
  264.             EmitDrawNode_r (node->children[i]);
  265.         }
  266.     }
  267.  
  268.     return n - dnodes;
  269. }
  270.  
  271. //=========================================================
  272.  
  273.  
  274. /*
  275. ============
  276. WriteBSP
  277. ============
  278. */
  279. void WriteBSP (node_t *headnode)
  280. {
  281.     int        oldfaces;
  282.  
  283.     c_nofaces = 0;
  284.     c_facenodes = 0;
  285.  
  286.     qprintf ("--- WriteBSP ---\n");
  287.  
  288.     oldfaces = numfaces;
  289.     dmodels[nummodels].headnode = EmitDrawNode_r (headnode);
  290.     EmitAreaPortals (headnode);
  291.  
  292.     qprintf ("%5i nodes with faces\n", c_facenodes);
  293.     qprintf ("%5i nodes without faces\n", c_nofaces);
  294.     qprintf ("%5i faces\n", numfaces-oldfaces);
  295. }
  296.  
  297. //===========================================================
  298.  
  299. /*
  300. ============
  301. SetModelNumbers
  302. ============
  303. */
  304. void SetModelNumbers (void)
  305. {
  306.     int        i;
  307.     int        models;
  308.     char    value[10];
  309.  
  310.     models = 1;
  311.     for (i=1 ; i<num_entities ; i++)
  312.     {
  313.         if (entities[i].numbrushes)
  314.         {
  315.             sprintf (value, "*%i", models);
  316.             models++;
  317.             SetKeyValue (&entities[i], "model", value);
  318.         }
  319.     }
  320.  
  321. }
  322.  
  323. /*
  324. ============
  325. SetLightStyles
  326. ============
  327. */
  328. #define    MAX_SWITCHED_LIGHTS    32
  329. void SetLightStyles (void)
  330. {
  331.     int        stylenum;
  332.     char    *t;
  333.     entity_t    *e;
  334.     int        i, j;
  335.     char    value[10];
  336.     char    lighttargets[MAX_SWITCHED_LIGHTS][64];
  337.  
  338.  
  339.     // any light that is controlled (has a targetname)
  340.     // must have a unique style number generated for it
  341.  
  342.     stylenum = 0;
  343.     for (i=1 ; i<num_entities ; i++)
  344.     {
  345.         e = &entities[i];
  346.  
  347.         t = ValueForKey (e, "classname");
  348.         if (Q_strncasecmp (t, "light", 5))
  349.             continue;
  350.         t = ValueForKey (e, "targetname");
  351.         if (!t[0])
  352.             continue;
  353.         
  354.         // find this targetname
  355.         for (j=0 ; j<stylenum ; j++)
  356.             if (!strcmp (lighttargets[j], t))
  357.                 break;
  358.         if (j == stylenum)
  359.         {
  360.             if (stylenum == MAX_SWITCHED_LIGHTS)
  361.                 Error ("stylenum == MAX_SWITCHED_LIGHTS");
  362.             strcpy (lighttargets[j], t);
  363.             stylenum++;
  364.         }
  365.         sprintf (value, "%i", 32 + j);
  366.         SetKeyValue (e, "style", value);
  367.     }
  368.  
  369. }
  370.  
  371. //===========================================================
  372.  
  373. /*
  374. ============
  375. EmitBrushes
  376. ============
  377. */
  378. void EmitBrushes (void)
  379. {
  380.     int            i, j, bnum, s, x;
  381.     dbrush_t    *db;
  382.     mapbrush_t        *b;
  383.     dbrushside_t    *cp;
  384.     vec3_t        normal;
  385.     vec_t        dist;
  386.     int            planenum;
  387.  
  388.     numbrushsides = 0;
  389.     numbrushes = nummapbrushes;
  390.  
  391.     for (bnum=0 ; bnum<nummapbrushes ; bnum++)
  392.     {
  393.         b = &mapbrushes[bnum];
  394.         db = &dbrushes[bnum];
  395.  
  396.         db->contents = b->contents;
  397.         db->firstside = numbrushsides;
  398.         db->numsides = b->numsides;
  399.         for (j=0 ; j<b->numsides ; j++)
  400.         {
  401.             if (numbrushsides == MAX_MAP_BRUSHSIDES)
  402.                 Error ("MAX_MAP_BRUSHSIDES");
  403.             cp = &dbrushsides[numbrushsides];
  404.             numbrushsides++;
  405.             cp->planenum = b->original_sides[j].planenum;
  406.             cp->texinfo = b->original_sides[j].texinfo;
  407.         }
  408.  
  409.         // add any axis planes not contained in the brush to bevel off corners
  410.         for (x=0 ; x<3 ; x++)
  411.             for (s=-1 ; s<=1 ; s+=2)
  412.             {
  413.             // add the plane
  414.                 VectorCopy (vec3_origin, normal);
  415.                 normal[x] = s;
  416.                 if (s == -1)
  417.                     dist = -b->mins[x];
  418.                 else
  419.                     dist = b->maxs[x];
  420.                 planenum = FindFloatPlane (normal, dist);
  421.                 for (i=0 ; i<b->numsides ; i++)
  422.                     if (b->original_sides[i].planenum == planenum)
  423.                         break;
  424.                 if (i == b->numsides)
  425.                 {
  426.                     if (numbrushsides >= MAX_MAP_BRUSHSIDES)
  427.                         Error ("MAX_MAP_BRUSHSIDES");
  428.  
  429.                     dbrushsides[numbrushsides].planenum = planenum;
  430.                     dbrushsides[numbrushsides].texinfo =
  431.                         dbrushsides[numbrushsides-1].texinfo;
  432.                     numbrushsides++;
  433.                     db->numsides++;
  434.                 }
  435.             }
  436.  
  437.     }
  438.  
  439. }
  440.  
  441. //===========================================================
  442.  
  443. /*
  444. ==================
  445. BeginBSPFile
  446. ==================
  447. */
  448. void BeginBSPFile (void)
  449. {
  450.     // these values may actually be initialized
  451.     // if the file existed when loaded, so clear them explicitly
  452.     nummodels = 0;
  453.     numfaces = 0;
  454.     numnodes = 0;
  455.     numbrushsides = 0;
  456.     numvertexes = 0;
  457.     numleaffaces = 0;
  458.     numleafbrushes = 0;
  459.     numsurfedges = 0;
  460.  
  461.     // edge 0 is not used, because 0 can't be negated
  462.     numedges = 1;
  463.  
  464.     // leave vertex 0 as an error
  465.     numvertexes = 1;
  466.  
  467.     // leave leaf 0 as an error
  468.     numleafs = 1;
  469.     dleafs[0].contents = CONTENTS_SOLID;
  470. }
  471.  
  472.  
  473. /*
  474. ============
  475. EndBSPFile
  476. ============
  477. */
  478. void EndBSPFile (void)
  479. {
  480.     char    path[1024];
  481.     int        len;
  482.     byte    *buf;
  483.  
  484.  
  485.     EmitBrushes ();
  486.     EmitPlanes ();
  487.     UnparseEntities ();
  488.  
  489.     // load the pop
  490. #if 0
  491.     sprintf (path, "%s/pics/pop.lmp", gamedir);
  492.     len = LoadFile (path, &buf);
  493.     memcpy (dpop, buf, sizeof(dpop));
  494.     free (buf);
  495. #endif
  496.  
  497.     // write the map
  498.     sprintf (path, "%s.bsp", source);
  499.     printf ("Writing %s\n", path);
  500.     WriteBSPFile (path);
  501. }
  502.  
  503.  
  504. /*
  505. ==================
  506. BeginModel
  507. ==================
  508. */
  509. int    firstmodleaf;
  510. extern    int firstmodeledge;
  511. extern    int    firstmodelface;
  512. void BeginModel (void)
  513. {
  514.     dmodel_t    *mod;
  515.     int            start, end;
  516.     mapbrush_t    *b;
  517.     int            j;
  518.     entity_t    *e;
  519.     vec3_t        mins, maxs;
  520.  
  521.     if (nummodels == MAX_MAP_MODELS)
  522.         Error ("MAX_MAP_MODELS");
  523.     mod = &dmodels[nummodels];
  524.  
  525.     mod->firstface = numfaces;
  526.  
  527.     firstmodleaf = numleafs;
  528.     firstmodeledge = numedges;
  529.     firstmodelface = numfaces;
  530.  
  531.     //
  532.     // bound the brushes
  533.     //
  534.     e = &entities[entity_num];
  535.  
  536.     start = e->firstbrush;
  537.     end = start + e->numbrushes;
  538.     ClearBounds (mins, maxs);
  539.  
  540.     for (j=start ; j<end ; j++)
  541.     {
  542.         b = &mapbrushes[j];
  543.         if (!b->numsides)
  544.             continue;    // not a real brush (origin brush)
  545.         AddPointToBounds (b->mins, mins, maxs);
  546.         AddPointToBounds (b->maxs, mins, maxs);
  547.     }
  548.  
  549.     VectorCopy (mins, mod->mins);
  550.     VectorCopy (maxs, mod->maxs);
  551. }
  552.  
  553.  
  554. /*
  555. ==================
  556. EndModel
  557. ==================
  558. */
  559. void EndModel (void)
  560. {
  561.     dmodel_t    *mod;
  562.  
  563.     mod = &dmodels[nummodels];
  564.  
  565.     mod->numfaces = numfaces - mod->firstface;
  566.  
  567.     nummodels++;
  568. }
  569.  
  570.